package com.back.handler;

import com.back.excepction.BaseException;
import com.back.model.reslut.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DataAccessException;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.jdbc.BadSqlGrammarException;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolationException;
import java.sql.SQLException;

@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    // 拦截SQL语法错误（你的核心错误）
    @ExceptionHandler(BadSqlGrammarException.class)
    public Result<?> handleBadSqlGrammar(BadSqlGrammarException e) {
        // 只打印一次完整堆栈，包含SQL语句和错误原因
        log.error("数据库SQL语法错误！SQL: {}, 原因: {}", e.getSql(), e.getMessage(), e);
        return Result.faile("数据库配置错误，请联系管理员");
    }

    // 拦截其他数据库相关异常
    @ExceptionHandler({SQLException.class, DataAccessException.class})
    public Result<?> handleDatabaseException(Exception e) {
        log.error("数据库操作失败", e);
        return Result.faile("数据库操作失败，请联系管理员");
    }



    @ExceptionHandler
    public Result BaseExceptionHandler(BaseException e){
        return Result.faile(e.getMessage());
    }
    /**
     * 处理请求参数格式错误 @RequestBody 上使用 @Valid 实体上使用 @NotNull 等，验证失败后抛出的异常是 MethodArgumentNotValidException
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result MethodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {
        log.error("MethodArgumentNotValidException: "+e.getMessage());
        String message = e.getBindingResult().getAllErrors().get(0).getDefaultMessage();
        log.info("fieldName:{}",message);
        return Result.faile(message);
    }

    /**
     * 处理 Get 请求中 使用 @Valid 验证路径中请求实体校验失败后抛出的异常
     */
    @ExceptionHandler(BindException.class)
    public Result BindExceptionHandler(BindException e) {
        log.error("BindException "+e.getMessage());
        String message = e.getBindingResult().getAllErrors().get(0).getDefaultMessage();
        return Result.faile(message);
    }

    /**
     * 处理请求参数格式错误 @RequestParam 上 @Validate 失败后抛出的异常是 ConstraintViolationException
     */
    @ExceptionHandler(ConstraintViolationException.class)
    public Result ConstraintViolationExceptionHandler(ConstraintViolationException e) {
        log.error("ConstraintViolationException "+e.getMessage());
        return Result.faile(e.getMessage());
    }

    /**
     * 参数格式异常
     */
    @ExceptionHandler(HttpMessageNotReadableException.class)
    public Result HttpMessageNotReadableExceptionHandler(HttpMessageNotReadableException e) {
        log.error("HttpMessageNotReadableException  "+e.getMessage());
        return Result.faile(e.getMessage());
    }
}
